package cl.solidit.geomanagement.web.controller;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import cl.solidit.geomanagement.persistance.ComunaDAO;
import cl.solidit.geomanagement.persistance.PersonaDAO;
import cl.solidit.geomanagement.persistance.PropiedadDAO;
import cl.solidit.geomanagement.persistance.UserDAO;
import cl.solidit.geomanagement.persistance.VisitaDAO;
import cl.solidit.geomanagement.persistance.model.Comuna;
import cl.solidit.geomanagement.persistance.model.Persona;
import cl.solidit.geomanagement.persistance.model.PreguntaRealizada;
import cl.solidit.geomanagement.persistance.model.Propiedad;
import cl.solidit.geomanagement.persistance.model.Usuario;
import cl.solidit.geomanagement.persistance.model.Visita;
import cl.solidit.geomanagement.web.service.RegisterPersonsService;

@Controller
public class RegisterVisitasController {
	@Autowired
	private VisitaDAO visitaDAO;
	@Autowired
	private PropiedadDAO propiedadDAO;
	@Autowired
	private PersonaDAO personaDAO;
	@Autowired
	private ComunaDAO comunaDAO;
	@Autowired
	private UserDAO userDAO;
	@Autowired
	private ConsultarVisitaController consultarVisitaController;
	@Autowired
	private ControlPanelController controlPanelController;
	@Autowired
	private RegisterPersonsService registerPersonsService;

	@Transactional
	@RequestMapping(value = "/crear_visita/{numeroPropiedad}", method = RequestMethod.GET)
	public ModelAndView loadPropiedad(@PathVariable Long numeroPropiedad) {
		Propiedad propiedad = propiedadDAO.consultarPropiedad(numeroPropiedad);
		Map<String, Object> map = new HashMap<String, Object>();
		List<Comuna> listaComunas = comunaDAO.traerComuna();
		map.put("listaComunas", listaComunas);
		Persona persona = new Persona();
		persona.setComuna(new Comuna());
		map.put("command", persona);
		map.put("propiedad", propiedad);
		map.put("persona", persona);

		return new ModelAndView("crear_visita", map);
	}

	@Transactional
	@RequestMapping(value = "/crear_visita/{numeroPropiedad}", method = RequestMethod.POST)
	public ModelAndView addVisita(@ModelAttribute("command") Persona persona,
			@PathVariable Long numeroPropiedad, HttpServletRequest request,
			@RequestParam(required = false, defaultValue = "0") Integer origen) {
		// persona.setFechaIngreso(new Date());
		Usuario u = personaDAO.findByRut(
				(String) request.getSession().getAttribute("rut")).getUsuario();
		registerPersonsService.registrarPersona(persona);
		Visita visita = new Visita();
		Propiedad p = propiedadDAO.consultarPropiedad(numeroPropiedad);
		p.setUltimaVisita(new Date());
		visita.setPropiedad(p);
		visita.setCliente(persona);
		visita.setFechaRegistro(new Date());
		visita.setFechaProgramada(new Date());
		visita.setAgente(u);
		visitaDAO.create(visita);
		return getFinishVisita(visita.getId(), origen);
	}

	@Transactional
	@RequestMapping(value = "/finalizar_visita/{idVisita}", method = RequestMethod.GET)
	public ModelAndView getFinishVisita(@PathVariable Long idVisita,
			@RequestParam(required = false, defaultValue = "0") Integer origen) {

		Visita visita = visitaDAO.findById(idVisita);

		Map<String, Object> map = new HashMap<String, Object>();
		List<PreguntaRealizada> preguntas = this.visitaDAO
				.consultarPreguntasRealizdasByPropiedad(visita.getPropiedad()
						.getId());
		for (PreguntaRealizada pregunta : preguntas) {
			Hibernate.initialize(pregunta.getVisita().getCliente());
		}
		map.put("propiedad", visita.getPropiedad());
		map.put("visita", visita);
		map.put("idVisita", idVisita);
		map.put("pregutas", preguntas);
		map.put("preguntasFrecuentes", visitaDAO.getPreguntasFrecuentes());
		map.put("origen", origen);
		return new ModelAndView("finalizar_visita", map);
	}

	@Transactional
	@RequestMapping(value = "/finalizar_visita/{idVisita}", method = RequestMethod.POST)
	public ModelAndView finishVisita(
			HttpServletRequest request,
			@PathVariable Long idVisita,
			@RequestParam(required = false) Integer percepcion,
			@RequestParam(required = false) @DateTimeFormat(pattern = "HH:mm") Date time,
			@RequestParam(required = false, defaultValue = "0") Integer origen,
			@RequestParam(required = false) String observacionCliente,
			@RequestParam(required = false) String observacionAgente,
			@RequestParam(required = false) String preguntaCompra,
			@RequestParam(required = false) String preguntaOferta,
			@RequestParam(required = false) Boolean ofertaRecibida,
			@RequestParam(required = false) BigDecimal ofertaValor) {

		Visita visita = visitaDAO.findById(idVisita);

		if (percepcion != null) {
			visita.setPercepcion(percepcion);
			Date date = visita.getFechaProgramada();
			Calendar c1 = new GregorianCalendar();
			c1.setTime(date);
			Calendar c2 = new GregorianCalendar();
			c2.setTime(time);
			c1.set(Calendar.HOUR_OF_DAY, c2.get(Calendar.HOUR_OF_DAY));
			c1.set(Calendar.MINUTE, c2.get(Calendar.MINUTE));
			c1.set(Calendar.SECOND, 0);
			c1.set(Calendar.MILLISECOND, 0);
			visita.setFechaInicio(c1.getTime());
			visita.setLlegoCliente(true);
		} else {
			visita.setPercepcion(1);
			visita.setLlegoCliente(false);
		}

		Propiedad p = propiedadDAO.findById(visita.getPropiedad().getId());
		if (ofertaRecibida == null)
			p.setOfertada(false);
		else
			p.setOfertada(ofertaRecibida);
		visita.setObservacionAgente(observacionAgente);
		visita.setObservacionCliente(observacionCliente);
		visita.setPreguntaCompra(preguntaCompra);
		visita.setFechaTermino(new Date());
		visita.setOfertaValor(ofertaValor);
		visita.getPropiedad().setPercepcion(
				Math.max(visita.getPercepcion(), visita.getPropiedad()
						.getPercepcion()));
		if (origen == 1)
			return controlPanelController.agentPanel(request);
		else {
			return consultarVisitaController.accesoPagina(request);
		}
	}

	@Transactional
	@RequestMapping(value = "/crear_pregunta", method = RequestMethod.POST)
	public ModelAndView crearPregunta(@RequestParam String pregunta,
			@RequestParam(required = false) String respuesta,
			@RequestParam Long idVisita,
			@RequestParam(required = false, defaultValue = "0") Integer origen) {
		Visita visita = visitaDAO.findById(idVisita);
		PreguntaRealizada pre = new PreguntaRealizada();
		pre.setPregunta(pregunta.trim());
		pre.setRespuesta(respuesta.trim());
		pre.setRespondida(respuesta != null && respuesta.trim().length() > 0);
		pre.setVisita(visita);

		visita.getPreguntasRealizadas().add(pre);

		return getFinishVisita(idVisita, origen);
	}

	@Transactional
	@RequestMapping(value = "/programar_visita", method = RequestMethod.GET)
	public ModelAndView agendarVisita() {

		return new ModelAndView("programar_visita");
	}

	@Transactional
	@RequestMapping(value = "/programar_visita", method = RequestMethod.POST)
	public ModelAndView agendarVisitapost(@RequestParam Long numeroPropiedad) {

		Propiedad propiedad = propiedadDAO.consultarPropiedad(numeroPropiedad);
		return agendarVisita2Get(propiedad.getNumero());
	}

	@Transactional
	@RequestMapping(value = "/finalizar_agendar_visita/{numeroPropiedad}", method = RequestMethod.GET)
	public ModelAndView agendarVisita2Get(@PathVariable Long numeroPropiedad) {

		Propiedad propiedad = propiedadDAO.consultarPropiedad(numeroPropiedad);
		List<Comuna> listaComunas = comunaDAO.traerComuna();
		List<Usuario> listaAgentes = userDAO.traerAgentes();
		Map<String, Object> map = new HashMap<String, Object>();
		Persona persona = new Persona();
		persona.setComuna(new Comuna());
		persona.setFechaIngreso(new Date());
		map.put("listaComunas", listaComunas);
		map.put("command", persona);
		map.put("propiedad", propiedad);
		map.put("persona", persona);
		map.put("listaAgentes", listaAgentes);
		for (Usuario a : listaAgentes) {
			Hibernate.initialize(a.getPersona());
		}
		return new ModelAndView("finalizar_agendar_visita", map);
	}

	@Transactional
	@RequestMapping(value = "/finalizar_agendar_visita/{numeroPropiedad}", method = RequestMethod.POST)
	public ModelAndView finalizarAgendarVisitaPost(
			@ModelAttribute("command") Persona persona,
			@PathVariable Long numeroPropiedad,
			@RequestParam(required = false) Long idAgente,
			HttpServletRequest request,
			@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date fechaProgramada,
			@RequestParam(required = false) @DateTimeFormat(pattern = "HH:mm") Date time) {

		Visita visita = new Visita();
		if (request.getSession().getAttribute("rol").equals(2L)) {
			Usuario u = personaDAO.findByRut(
					(String) request.getSession().getAttribute("rut"))
					.getUsuario();
			visita.setAgente(u);
		} else {
			Usuario usuario = userDAO.findById(idAgente);
			visita.setAgente(usuario);
		}
		Propiedad propiedad = propiedadDAO.consultarPropiedad(numeroPropiedad);
		registerPersonsService.registrarPersona(persona);
		visita.setCliente(persona);
		visita.setPropiedad(propiedad);
		visita.setFechaRegistro(new Date());
		Calendar c1 = new GregorianCalendar();
		c1.setTime(fechaProgramada);
		Calendar c2 = new GregorianCalendar();
		c2.setTime(time);
		c1.set(Calendar.HOUR_OF_DAY, c2.get(Calendar.HOUR_OF_DAY));
		c1.set(Calendar.MINUTE, c2.get(Calendar.MINUTE));
		c1.set(Calendar.SECOND, 0);
		c1.set(Calendar.MILLISECOND, 0);
		visita.setFechaProgramada(c1.getTime());

		visitaDAO.create(visita);

		return new ModelAndView("visita_registrada");
	}

}
